#pragma once

//////////////////////////////////////////////////////////////////////////
/// The ADTChunkLoader implements the IGraphicsTask by loading all the 
/// graphics related stuff that needs to be done in the main thread of the
/// device. After the ChunkLoader is finished (indicated by the event) all
/// the graphics stuff is ready and can be rendered
//////////////////////////////////////////////////////////////////////////
class ADTChunkLoader : public IGraphicsTask
{
	Mesh mMesh;
	Vertex3FCNT2 rlVertices[145];
	bool mIsFinished;
public:
	ADTChunkLoader() : mIsFinished(false) {
	}

	bool isPriorityTask() { return true; }

	// Executes the work for one frame. Basically loads all the vertices
	// into the video memory and prepares it to be rendered. Do not call
	// it, its automatically called by the devices TaskManager.
	// Returns true if the task was finished, false else.
	bool execute();

	// Do not call this function, its called by the devices TaskManager after the
	// task has finished. The finishing event is called for other threads to
	// join it.
	void finish() {
		finishEvent.signal();
	}

	// Set the vertices used for this chunk. This does not mark the chunk as dirty.
	// Before the first execution you should call this function with valid vertices
	// after you can call it to change vertices.
	void setVertices(Vertex3FCNT2 (&vertices)[145]) {
		memcpy(rlVertices, vertices, 145 * sizeof(Vertex3FCNT2));
	}

	// Requests the mesh for the given vertices. Only valid after the task has finished!
	Mesh& getMesh() { return mMesh; }

	bool isFinished() const { return mIsFinished; }
};

class ADTLoader : public IGraphicsTask
{
	ADTChunkLoader mChunkLoaders[256];
	ui32 mCurIndex;
	Mutex mTextureLock, mIndexLock;
	std::queue<std::string> mTextureNames;
	std::vector<Texture*> mTextures;
	std::set<ui8> mIndicesToLoad;
protected:
	bool execute();

	bool isPriorityTask() { return true; }

	void finish() {
		finishEvent.signal();
	}
public:
	ADTChunkLoader& getChunk(ui8 index) { return mChunkLoaders[index]; }
	ADTLoader() : mCurIndex(0) {
	}

	void addTextures(std::vector<std::string>& textureNames);

	void setChunkDirty(ui8 index) {
		MUTEX_LOCK(mIndexLock);
		if(mIndicesToLoad.find(index) == mIndicesToLoad.end())
			mIndicesToLoad.insert(index);
		sD3D.getTaskMgr().pushTask(this);
	}

	void beginLoad() {
		sD3D.getTaskMgr().pushTask(this);
	}
};